package com.peak.distribution.web.validator;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.peak.spring.boot.tools.Emptys;
import com.peak.spring.boot.tools.Reflections;

public class Validator {
	
	private List<ValidateRule> rules;
	
	private Object obj;

	@SuppressWarnings("unchecked")
	public Valid validate(Map<Class<? extends ValidateRuleMethod>, ValidateRuleMethod> ruleMap) {
		if (rules == null) {
			throw new RuntimeException("未设置校验规则");
		}
		if (obj == null) {
			throw new RuntimeException("校验的对象是空对象");
		}
		Map<String, Object> map = Maps.newHashMap();
		if (obj instanceof Map) {// 默认就是Map
			map = (Map<String, Object>) obj;
		} else {// 是对象的也转换成Map
			List<Field> fields = Reflections.getAllDeclaredField(obj.getClass(), Object.class);
			for (Field field : fields) {
				String fieldName = field.getName();
				Method value = Reflections.getAccessibleMethodByName(field, "get" + StringUtils.capitalize(fieldName));
				map.put(fieldName, value);
			}
		}
		Valid valid = new Valid();
		boolean isAllFieldValid = true;
		for (ValidateRule rule : rules) {
			Object value = map.get(rule.getProptertyName());
			boolean isAllValid = true;
			for (Class<? extends ValidateRuleMethod> methodClass : rule.getMethods()) {
				ValidateRuleMethod method = ruleMap.get(methodClass);
				Map<String, Object> params = rule.getMethodParam().get(methodClass);
				if (Emptys.isNotEmpty(params)) {
					method.setParams(params);
				}
				boolean isValid = method.execute(value);
				if (!isValid) {// 验证一个错误就不继续验证了
					String formatMsg = null;
					if (Emptys.isNotEmpty(params)) {
						formatMsg = MessageFormat.format(method.getErrorMessageTemplate(), rule.getProptertyTitle(), params.get("msgArgs"));
					} else {
						formatMsg = MessageFormat.format(method.getErrorMessageTemplate(), rule.getProptertyTitle());
					}
					valid.getErrorMessages().add(formatMsg);
					isAllValid = false;
					break;
				}
			}
			if (!isAllValid) {
				isAllFieldValid = false;
			}
			valid.getPropertyValids().put(rule.getProptertyName(), isAllValid);
		}
		valid.setValid(isAllFieldValid);
		return valid;
	}
	
	public List<Valid> validateProperty(String propertyName) {
		return Lists.newArrayList();
	}

	public void setRule(List<ValidateRule> rules) {
		this.rules = rules;
	}

	public void setValidateObject(Object obj) {
		this.obj = obj;
	}
}
